from django.shortcuts import render,HttpResponse
from rest_framework.viewsets import ModelViewSet
# Create your views here.
from . import models
from .serializers import HostModelSerializer, HostCategoryModelSerializer
from rest_framework.permissions import IsAuthenticated  #校验用户是否处于登录状态
# JSONWebTokenAuthentication -- 对请求的请求头 Authenticated  : jwt token值
from rest_framework.generics import ListAPIView
from rest_framework.views import APIView
from hippo_api.utils.handle_excel import read_host_excel_data
from rest_framework.response import Response
from hippo_api.utils.handle_key import AppSetting
from rest_framework import status
from rest_framework.viewsets import ViewSet
import xlwt


class HostView(ModelViewSet):
    permission_classes = [IsAuthenticated, ]
    queryset = models.Host.objects.filter(is_show=True, is_deleted=False)
    serializer_class = HostModelSerializer

# NAME  AGE
class HostCategoryView(ListAPIView):
    permission_classes = [IsAuthenticated, ]
    queryset = models.HostCategory.objects.filter(is_show=True, is_deleted=False)
    serializer_class = HostCategoryModelSerializer

# 批量导入excel主机数据
class HostExcelView(APIView):
    permission_classes = [IsAuthenticated, ]

    def post(self,request):
        print(request.data)

        default_password = request.data.get('default_password') #'123'
        host_excel = request.data.get('host_excel') #'123'
        # 方式1 1 将文件保存到本机上
        # 2 读取excel文件数据
        print('host_excel>>>', host_excel)
        # 方式2 ： 将文件数据保存到byteio对象，内存字节流空间
        # host_excel_bytes = host_excel.open(mode='rb')
        from io import BytesIO, StringIO
        # 创建一个excel的临时存储目录(根目录下创建tem_file)，先保存excel文件到本地，然后读取数据，保存，最后删除excel文件。
        # sio = StringIO()
        sio = BytesIO()
        # file_path = f'{settings.BASE_DIR}/tem_file/{host_excel.name}'
        # with open(file_path, 'wb') as f:
        for i in host_excel:
            sio.write(i)


        # res_data = read_host_excel_data(file_path, default_password)
        res_data = read_host_excel_data(sio, default_password)
        # 拿到上传之后的数据之后，我们删掉上传上来的临时excel文件

        # import os
        # if os.path.exists(file_path):  # 如果文件存在
        #     # 删除文件，可使用以下两种方法。
        #     os.remove(file_path)
        #     # os.unlink(path)
        # else:
        #     print('没有该文件:%s' % file_path)  # 则返回文件不存在

        return Response(res_data)



    # 下载host数据excel文件
    def get(self, request):
        # 1 读取数据库数据
        all_host_data = models.Host.objects.all().values('id', 'category', 'hostname', 'ip_addr', 'port',
                                                         'username', 'desc',)
        print(all_host_data)

        # 2 写入
        # excel并保存
        # 关于excel的操作，参考我的博客
        # 创建excel
        ws = xlwt.Workbook(encoding='utf-8')
        # 创建工作簿
        st = ws.add_sheet('主机数据')

        # 写标题行
        st.write(0, 0, 'id')
        st.write(0, 1, 'category')
        st.write(0, 2, 'hostname')
        st.write(0, 3, 'ip_addr')
        st.write(0, 4, 'port')
        st.write(0, 5, 'username')
        st.write(0, 6, 'desc')
        st.write(0, 7, 'evrironments')

        # 写入数据，从第一行开始
        excel_row = 1
        for host_obj in all_host_data:
            st.write(excel_row, 0, host_obj.get('id'))
            st.write(excel_row, 1, host_obj.get('category'))
            st.write(excel_row, 2, host_obj.get('hostname'))
            st.write(excel_row, 3, host_obj.get('ip_addr'))
            st.write(excel_row, 4, host_obj.get('port'))
            st.write(excel_row, 5, host_obj.get('username'))
            st.write(excel_row, 6, host_obj.get('desc'))
            st.write(excel_row, 7, host_obj.get('evrironments'))
            excel_row += 1

        # sio = BytesIO()
        from io import BytesIO
        # 将数据写入io数据流，不用在本地生成excel文件，不然效率就低了
        sio = BytesIO()
        ws.save(sio)
        sio.seek(0)
        # print(sio.getvalue())

        # 3 将excel数据响应回客户端
        response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
        # response['Content-Disposition'] = 'attachment; filename=xx.xls'

        # 文件名称中文设置
        from django.utils.encoding import escape_uri_path
        response['Content-Disposition'] = 'attachment; filename={}'.format(escape_uri_path('主机列表数据.xls'))
        response.write(sio.getvalue())  # 必须要给response写入一下数据，不然不生效

        return response

    # def get(self,request):
#
# from hippo_api.utils.handle_key import AppSetting
# from rest_framework import status
# from rest_framework.viewsets import ViewSet
# class HostFileView(ViewSet):
#     # 方法分发之前，先获取要操作的主机id和链接
#     def dispatch(self, request, *args, **kwargs):
#         pk = kwargs.get('pk')
#         host_obj = models.Host.objects.get(pk=pk)
#         pkey = AppSetting.get('private_key')
#         cli = host_obj.get_ssh(pkey)
#         self.cli = cli
#         ret = super().dispatch(request, *args, **kwargs)
#
#         return ret
#
#     # get_folders获取某个目录的文件和文件夹信息列表
#     def get_folders(self, request, pk):
#         # cmd = request.query_params.get('cmd')  #
#
#         cmd = request.query_params.get('cmd')  # ls  ls-a
#
#         res_code, res_data = self.cli.exec_command(cmd)
#         # print('!!!!!!!', res_code,res_data)
#         return Response([res_code, res_data])
#         # res_code, res_data = self.cli.exec_command(cmd)
#         # print('!!!!!!!', res_code,res_data)
#         # result = self.cli.list_dir_attr('/bin')
#
#         # print()
#         # file_info_list = []
#         #
#         # for i in result:
#         #     file_info_dict = {
#         #         'ks': i.ks,
#         #         'st_uid': i.st_uid,
#         #         'st_gid': i.st_gid,
#         #         'st_mode': i.st_mode,
#         #         'st_atime': i.st_atime,
#         #         'st_mtime': i.st_mtime,
#         #
#         #     }
#         #     file_info_list.append(file_info_dict)
#         #
#         # print('>>>>>>>>>',file_info_list)
#
#     def download_file(self, request, pk, file_path):
#         pass
#
#     def upload_file(self, request, pk):
#         folder_path = request.query_params.get('folder_path')  #/home
#
#         file_obj = request.FILES.get('file')
#         folder_path += f'/{file_obj.name}'  # /home/xx.txt
#         # print(folder_path)
#         file_size = file_obj.size
#
#         try:
#             self.cli.put_file_by_fl(file_obj, folder_path, self.file_upload_callback)
#         except:
#             return Response({'error': '文件上传失败,请联系管理员或者查看一下用户权限'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
#
#         return Response({'msg': 'ok'})
#
#     def delete_file(self, request, file_path):
#         pass
#
#     def file_upload_callback(self, n, k):
#         print('>>>>>>>>>>>', n, k)


class HostFileView(ViewSet):
    # 方法分发之前，先获取要操作的主机id和链接
    def dispatch(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        host_obj = models.Host.objects.get(pk=pk)
        pkey = AppSetting.get('private_key')
        cli = host_obj.get_ssh(pkey)
        self.cli = cli
        ret = super().dispatch(request, *args, **kwargs)

        return ret

    # get_folders获取某个目录的文件和文件夹信息列表
    def get_folders(self, request, pk):
        # cmd = request.query_params.get('cmd')  #

        cmd = request.query_params.get('cmd')  # ls  ls-a

        res_code, res_data = self.cli.exec_command(cmd)
        # print('!!!!!!!', res_code,res_data)
        return Response([res_code, res_data])
        # res_code, res_data = self.cli.exec_command(cmd)
        # print('!!!!!!!', res_code,res_data)
        # result = self.cli.list_dir_attr('/bin')

        # print()
        # file_info_list = []
        #
        # for i in result:
        #     file_info_dict = {
        #         'ks': i.ks,
        #         'st_uid': i.st_uid,
        #         'st_gid': i.st_gid,
        #         'st_mode': i.st_mode,
        #         'st_atime': i.st_atime,
        #         'st_mtime': i.st_mtime,
        #
        #     }
        #     file_info_list.append(file_info_dict)
        #
        # print('>>>>>>>>>',file_info_list)

    def download_file(self, request, pk, file_path):
        pass

    def upload_file(self, request, pk):
        folder_path = request.query_params.get('folder_path')  #/home

        file_obj = request.FILES.get('file')
        folder_path += f'/{file_obj.name}'  # /home/xx.txt
        # print(folder_path)
        file_size = file_obj.size

        try:
            self.cli.put_file_by_fl(file_obj, folder_path, self.file_upload_callback)
        except:
            return Response({'error': '文件上传失败,请联系管理员或者查看一下用户权限'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({'msg': 'ok'})

    def delete_file(self, request, file_path):
        pass

    def file_upload_callback(self, n, k):
        pass
        # print('>>>>>>>>>>>', n, k)


